﻿using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ImgClip
{
    /// <summary>
    /// 
    /// </summary>
    public class HttpPocess : Pocess
    {
        private readonly LocalPocess _localPocess;
        private readonly ClipConfig _config;
        private readonly HttpClient _http;

        public HttpPocess(IHttpClientFactory factory,
            ClipConfig config,
            LocalPocess local)
        {
            _config = config;
            _http = factory.CreateClient(config.BaseUrl);
            _localPocess = local;
        }



        /// <summary>
        /// Get a remote image
        /// 加载网络图片(原图)
        /// </summary>
        /// <param name="requrestUrl"></param>
        /// <returns></returns>
        public Stream GetImage(string requrestUrl)
        {
            Stream stream = null;
            string url = GetFullUrl(requrestUrl);
            string name = Md5(url);
            string dirName = _localPocess.GetDirName(url); 
            if (_config.LocalSave)
                stream = _localPocess.Get(dirName, name);
            if (stream == null)
            {
                stream = RemoteImage(requrestUrl);
                if (_config.LocalSave)
                {
                    MemoryStream ms = new();
                    stream.CopyTo(ms);
                    _localPocess.SaveAsync(dirName, name, ms);
                }
            }
            return stream;
        }

        /// <summary>
        /// Get watermark image 
        /// </summary>
        /// <param name="base64Url">If the request address does not exist, the default configuration address is used</param>
        /// <returns></returns>
        public Stream GetWatermark(string base64Url)
        {
            if (String.IsNullOrEmpty(base64Url))
                return null;

            var bt = Convert.FromBase64String(base64Url);

            string requestUrl = Encoding.UTF8.GetString(bt);
            if (String.IsNullOrEmpty(requestUrl))
                return null;

            string fullUrl = GetFullUrl(WebUtility.UrlDecode(requestUrl));

            string key = Md5(fullUrl);
            Stream stream = _localPocess.GetWatermark(key);
            if (stream == null)
            {
                stream = RemoteImage(fullUrl);
                if (stream != null)
                {
                    MemoryStream ms = new();
                    stream.CopyTo(ms);
                    _localPocess.SaveWatermark(key, ms);
                }
            }
            return stream;
        }

        /// <summary>
        /// download remote image
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <returns></returns>
        private Stream RemoteImage(string requestUrl)
        {
            if (_http.BaseAddress == null)
            {
                if (!requestUrl.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
                    return null;
            }
            var res = _http.GetAsync(requestUrl).Result;
            if (res.IsSuccessStatusCode)
            {
                return res.Content.ReadAsStreamAsync().Result;
            }
            return null;
        }

        /// <summary>
        /// Get the full URL address
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <returns></returns>
        private string GetFullUrl(string requestUrl)
        {
            if (String.IsNullOrEmpty(requestUrl))
                return null;
            if (!requestUrl.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
                requestUrl = $"{_config.BaseUrl.TrimEnd('/')}/{requestUrl.Trim('/')}";
            return requestUrl.Trim('/');
        }
    }
}
